﻿using System;
using System.Workflow.ComponentModel;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.Sdk.Query;
using Microsoft.Crm.SdkTypeProxy;
using Microsoft.Crm.Workflow;

namespace CrmContrib.Workflow.Activities.Utilities
{
    [CrmWorkflowActivity("Get Related Entity ID", "CrmContrib \\ Utilities")]
    public class GetRelatedEntityIdActivity : Activity
    {
        [CrmInput("Parent Entity ID")]
        public string ParentEntityId
        {
            get { return (string)base.GetValue(ParentEntityIdProperty); }
            set { base.SetValue(ParentEntityIdProperty, value); }
        }

        public static readonly DependencyProperty ParentEntityIdProperty = DependencyProperty.Register("ParentEntityId", typeof(string), typeof(GetRelatedEntityIdActivity));

        [CrmInput("Parent Entity Name")]
        public string ParentEntityName
        {
            get { return (string)base.GetValue(ParentEntityNameProperty); }
            set { base.SetValue(ParentEntityNameProperty, value); }
        }

        public static readonly DependencyProperty ParentEntityNameProperty = DependencyProperty.Register("ParentEntityName", typeof(string), typeof(GetRelatedEntityIdActivity));

        [CrmInput("Related Entity ID Column Name")]
        public string RelatedEntityIDColumn
        {
            get { return (string)base.GetValue(RelatedEntityIDColumnProperty); }
            set { base.SetValue(RelatedEntityIDColumnProperty, value); }
        }

        public static readonly DependencyProperty RelatedEntityIDColumnProperty = DependencyProperty.Register("RelatedEntityIDColumn", typeof(string), typeof(GetRelatedEntityIdActivity));

        /// <summary>
        /// Retrieve a specified column from the parent table
        /// </summary>
        /// <param name="executionContext"></param>
        /// <returns></returns>
        /// <remarks>The convention here is that the primary key on the table is of the form 'entityName'+id </remarks>
        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            var contextService = executionContext.GetService<IContextService>();
            var workflowContext = contextService.Context;
            var crmService = workflowContext.CreateCrmService();

            //equivalent to: select RelatedEntityIDColumn from ParentEntityName where ParentEntityIDColumn = ParentEntityId 
            var query = new QueryExpression { EntityName = ParentEntityName, ColumnSet = new ColumnSet() };
            query.ColumnSet.AddColumn(RelatedEntityIDColumn);
            query.Criteria.AddCondition(string.Format("{0}id", ParentEntityName.ToLower()), ConditionOperator.Equal, new Guid(ParentEntityId));

            //should only be one record if select with primary key
            var response = (RetrieveMultipleResponse)crmService.Execute(new RetrieveMultipleRequest { ReturnDynamicEntities = true, Query = query });
            RelatedEntityId = string.Empty;
            if (response.BusinessEntityCollection.BusinessEntities.Count > 0)
            {
                RelatedEntityId = ((CrmReference)((DynamicEntity)response.BusinessEntityCollection.BusinessEntities[0])[RelatedEntityIDColumn]).Value.ToString();
            }

            return base.Execute(executionContext);
        }

        [CrmOutput("Related Entity ID")]
        public string RelatedEntityId
        {
            get { return (string)GetValue(RelatedEntityIdProperty); }
            set { SetValue(RelatedEntityIdProperty, value); }
        }

        public static readonly DependencyProperty RelatedEntityIdProperty = DependencyProperty.Register("RelatedEntityId", typeof(string), typeof(GetRelatedEntityIdActivity));

    }
}
